﻿using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal;
using Models.Common;
using Models.Device;
using Models.Task;
using Nancy.TinyIoc;
using Newtonsoft.Json;

using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Data;
using System.Linq;
using System.Reflection.Metadata;
using System.Text;
using System.Threading.Tasks;
using static Models.Common.EnumDeviceState;
using UtilsCache;
using GatewayServerService.Data;
using UtilsORM;
using UtilsORM.MySqlData;
using InfluxData.Net.InfluxDb.Models.Responses;
using UtilsBase;
using Models.WebClient;
using GatewayServerService.CloudCenter;

namespace GatewayServerService.CloudCenter
{
    /// <summary>
    /// 定时任务执行
    /// </summary>
    public class ServiceCloudTaskTime
    {

        public void taskRun()
        {
            Task.Run(() =>
            {
                try
                {
                    //更新，防止 单机版主板时间 不同步了，重启后ti_execute_time会大于now(),然后不再运行
                    string sql = "update iot_device_task_time_interval set ti_execute_time=date_add(now(),INTERVAL  -10 HOUR) where ti_execute_time>now() or ti_execute_time is null";
                    MySqlYihongIot.ExecuteCommand(sql);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }

                while (true)
                {
                    //DateTime dtStart = System.DateTime.Now;
                    try
                    {
                        //当多节点时，同时只有一处执行
                        getTimeTask_interval();//时间间隔                                             

                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.ToString());
                    }

                    //TimeSpan ts = DateTime.Now - dtStart;
                    //if (ts.TotalMilliseconds < 1000)
                    //{
                    //    Thread.Sleep(1000 - (int)ts.TotalMilliseconds);
                    //}
                    Thread.Sleep(1000);
                }
            });

            Task.Run(() =>
            {
                try
                {
                    //更新，防止 单机版主板时间 不同步了，重启后ti_execute_time会大于now(),然后不再运行
                    string sql = "update iot_device_task_time_fixed set tf_execute_time=date_add(now(),INTERVAL  -10 HOUR) where tf_execute_time>now() or tf_execute_time is null";
                    MySqlYihongIot.ExecuteCommandAsync(sql);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
                while (true)
                {

                    try
                    {

                        //当多节点时，同时只有一处执行
                        getTimeTask_fixed();//指定时间点                                          

                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.ToString());
                    }
                    Thread.Sleep(1000);
                }
            });
        }


        /// <summary>
        /// 按时间间隔进行定时
        /// </summary>
        public void getTimeTask_interval()
        {

            try
            {

                string dtnow = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                string sql = "select * from iot_device_task_time_interval where  ti_status=0 and  ti_execute_time<=date_add('" + dtnow + "',INTERVAL  -ti_interval_value SECOND)";
                List<iot_device_task_time_interval> time_Intervals = MySqlYihongIot.GetList<iot_device_task_time_interval>(sql);
                foreach (iot_device_task_time_interval item in time_Intervals)
                {
                    try
                    {

                        string sqlUpd = "update iot_device_task_time_interval set  ti_execute_time='" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "',ti_execute_count=IFNULL(ti_execute_count,0)+1 where ti_id='" + item.ti_id + "'";
                        MySqlYihongIot.ExecuteCommand(sqlUpd);
                        //到时间执行
                        Task.Run(() =>
                        {
                            //var lockobj = UtilFreeRedis.getLock("getTimeTask_interval_" + item.ti_task_guid, 1);
                            //if (lockobj != null)
                            //{
                            if (item.ti_task_type == "taskplain")
                            {
                                new ServiceCloudTaskPlain().getTaskPlianTask(item.ti_task_guid);
                            }
                            else if (item.ti_task_type == "device")
                            {
                                device(item.ti_task_guid, item.ti_key);
                            }

                            new DBIotDeviceTaskTimeIntervalLog().saveLogSync(item);

                            //    lockobj.Unlock();
                            //}
                        });
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.ToString());
                    }


                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

        }
        //private static object obj2 = new object();
        /// <summary>
        /// 按指定时间点进行定时
        /// </summary>
        public async void getTimeTask_fixed()
        {

            try
            {

                EFYihongIotContext ef = new EFYihongIotContext();
                // List<iot_device_task_time_fixed> time_Intervals = ef.iot_device_task_time_fixed.Where(c => c.tf_start_time < DateTime.Now && c.tf_status == 0).ToList();

                string startDate = DateTime.Now.ToString("yyyy-MM-dd ");
                //string sql = "select * from iot_device_task_time_fixed where tf_status=0 and   tf_execute_time<STR_TO_DATE(CONCAT('" + startDate + "',tf_time_value),'%Y-%m-%d %H:%i:%s') and  now()>=STR_TO_DATE(CONCAT('" + startDate + "',tf_time_value),'%Y-%m-%d %H:%i:%s') and now()>STR_TO_DATE(DATE_ADD(tf_execute_time ,INTERVAL tf_interval_day DAY),'%Y-%m-%d')";
                string sql = "select * from iot_device_task_time_fixed where tf_status=0 and   tf_execute_time<STR_TO_DATE(CONCAT('" + startDate + "',tf_time_value),'%Y-%m-%d %H:%i:%s') and DATE_FORMAT(now(),'%Y-%m-%d %H:%i') =DATE_FORMAT(STR_TO_DATE(CONCAT('" + startDate + "',tf_time_value),'%Y-%m-%d %H:%i'),'%Y-%m-%d %H:%i') and now()>STR_TO_DATE(DATE_ADD(tf_execute_time ,INTERVAL tf_interval_day DAY),'%Y-%m-%d')";
                List<iot_device_task_time_fixed> time_Intervals = MySqlYihongIot.GetList<iot_device_task_time_fixed>(sql);

                foreach (iot_device_task_time_fixed item in time_Intervals)
                {

                    try
                    {
                        //判断运行时间，是否跟现在是同一分钟内，否则不运行                     

                        string sqlUpd = "update iot_device_task_time_fixed set  tf_execute_time='" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "',tf_execute_count=IFNULL(tf_execute_count,0)+1 where tf_id='" + item.tf_id + "'";
                        MySqlYihongIot.ExecuteCommand(sqlUpd);

                        //到时间执行
                        Task.Run(() =>
                        {
                            if (item.tf_task_type == "taskplain")
                            {
                                new ServiceCloudTaskPlain().getTaskPlianTask(item.tf_task_guid);
                            }
                            else if (item.tf_task_type == "device")
                            {
                                device(item.tf_task_guid, item.tf_key);
                            }

                        });

                        Task.Run(() =>
                        {
                            new DBIotDeviceTaskTimeFixedLog().saveLog(item);
                        });

                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.ToString());
                    }
                }
                ef.Dispose();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

        }


        public void device(string taskGuid, string key)
        {
            try
            {
                EFYihongIotContext ef2 = new EFYihongIotContext();
                iot_device iot_Device = ef2.iot_device.Where(c => c.d_guid == taskGuid && c.d_status == 0).FirstOrDefault();
                if (iot_Device == null)
                { return; }

                iot_device_live_state gwlivestate = ef2.iot_device_live_state.Where(c => c.ls_d_guid == iot_Device.d_gw_d_guid && c.ls_live_state_set_time > DateTime.Now.AddMinutes(-2)).FirstOrDefault();
                //判断主机是否在线，在线才执行
                if (gwlivestate == null)
                {
                    Console.WriteLine(" 执行内容 iot_Device 主机不在线 ");
                    return;
                }


                new ServiceCloudDeviceCommand().sendCommandToGateWay(iot_Device.d_guid, key, "定时/时间任务 taskGuid:" + taskGuid);
                ef2.Dispose();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
    }
}
